#include "main.h"

PortConfig port_configs[NUM_PORTS] =
{
    {502, "/dev/ttyS1", 9600, 8, 1, 0, false},
    {503, "/dev/ttyS2", 9600, 8, 1, 0, false},
    {504, "/dev/ttyS3", 9600, 8, 1, 0, false},
    {505, "/dev/ttyS4", 9600, 8, 1, 0, false},
    {506, "/dev/ttyS5", 9600, 8, 1, 0, false},
    {507, "/dev/ttyS6", 9600, 8, 1, 0, false},
    {508, "/dev/ttyS7", 9600, 8, 1, 0, false},
    {509, "/dev/ttyS8", 9600, 8, 1, 0, false}
};

void *port_thread(void *arg)
{
    int index = *(int *)arg;
    free(arg);

    PortConfig *config = &port_configs[index];

    int tcp_fd = create_tcp_server(config->port);
    if (tcp_fd < 0)
    {
        fprintf(stderr, "Failed to create TCP server on port %d\n", config->port);
        return NULL;
    }

    printf("Listening on port %d for device %s\n", config->port, config->serial_device);

    while (1)
    {
        int client_fd = accept_tcp_connection(tcp_fd);
        if (client_fd < 0)
        {
            perror("accept");
            continue;
        }

        int serial_fd = open_serial_port(config->serial_device);
        if (serial_fd < 0)
        {
            close(client_fd);
            continue;
        }

        if (configure_serial_port(serial_fd, config->baud_rate, config->data_bits,
                                  config->stop_bits, config->parity, config->flow_control) < 0)
        {
            close_serial_port(serial_fd);
            close(client_fd);
            continue;
        }

        printf("Connection established: Port %d, TCP %d, Serial %s\n",
               config->port, client_fd, config->serial_device);

        // 数据转发循环
        while (1)
        {
            fd_set read_fds;
            FD_ZERO(&read_fds);
            FD_SET(client_fd, &read_fds);
            FD_SET(serial_fd, &read_fds);

            int max_fd = (client_fd > serial_fd) ? client_fd : serial_fd;

            struct timeval timeout;
            timeout.tv_sec = 0;
            timeout.tv_usec = 50000;  // 50ms 超时

            if (select(max_fd + 1, &read_fds, NULL, NULL, &timeout) < 0)
            {
                perror("select");
                break;
            }

            // TCP -> 串口
            if (FD_ISSET(client_fd, &read_fds))
            {
                char buffer[BUFFER_SIZE];
                ssize_t bytes_read = read(client_fd, buffer, sizeof(buffer));
                if (bytes_read <= 0)
                    break;

                ssize_t bytes_written = write(serial_fd, buffer, bytes_read);
                if (bytes_written != bytes_read)
                {
                    perror("serial write");
                    break;
                }
            }

            // 串口 -> TCP
            if (FD_ISSET(serial_fd, &read_fds))
            {
                char buffer[BUFFER_SIZE];
                ssize_t bytes_read = read(serial_fd, buffer, sizeof(buffer));
                if (bytes_read <= 0) break;

                ssize_t bytes_written = write(client_fd, buffer, bytes_read);
                if (bytes_written != bytes_read)
                {
                    perror("tcp write");
                    break;
                }
            }
        }

        printf("Connection closed: Port %d\n", config->port);
        close_serial_port(serial_fd);
        close(client_fd);
    }

    close(tcp_fd);
    return NULL;
}

void start_server()
{
    pthread_t threads[NUM_PORTS];

    for (int i = 0; i < NUM_PORTS; i++)
    {
        int *index = malloc(sizeof(int));
        *index = i;

        if (pthread_create(&threads[i], NULL, port_thread, index) != 0)
        {
            perror("pthread_create");
            free(index);
        }
    }

    for (int i = 0; i < NUM_PORTS; i++)
    {
        pthread_join(threads[i], NULL);
    }
}

int main()
{
    start_server();

    return 0;
}
